<html>
<head>
<style>
body {
	font-family: sans-serif;
}
code {
	background: #ddd;
}
pre {
	margin: 0 2em;
	padding: 0.5em;
	background: #ddd;
}
.spoiler {
	overflow: hidden;
	background: black;
	width: 50px;
	height: 15px;
}
.spoiler:hover {
	background: #ddd;
	height: auto;
	width: auto;
}
</style>
</head>
<body>

<h1>Get Started with Go</h1>

<h2>Introduction</h2>

<p>Welcome to this Go tutorial!</p>

<p>This tutorial is split into two sessions. You'll watch a short presentation at
the beginning of each session, and then be left to work on the exercises in
this document.</p>

<p>It's not expected that you should finish them in the short time we have,
so don't be discouraged if you feel like you're not making progress.</p>

<p>At the end of each exercise is a spoiler box.
Hover over the box to see the solution:</p>

<pre class="spoiler">
But only peek when you REALLY need to!
</pre>

<p>Don't be afraid to ask the lecturer, one of the teaching assistants, or other
students for help.</p>

<p>Without further ado, the exercises!</p>

<h2>Session one</h2>

<h3>Hello, world</h3>

<p>Copy this code into a file named <code>hello.go</code>:</p>

<pre>package main

import "fmt"

func main() {
    fmt.Println("Hello, world")
}

</pre>

<p>Build and link the file using <code>6g</code> and <code>6l</code>
(or, if you're using a 32-bit system, <code>8g</code> and <code>8l</code>):</p>

<pre><code>$ 6g hello.go
$ 6l hello.6
</code></pre>

<p>This will produce an executable named <code>6.out</code> (or <code>8.out</code>).
Run it, and you should see the <code>Hello, world</code> message.</p>

<pre><code>$ ./6.out
Hello, world
</code></pre>

<p>You can run these three commands on the same line to quickly
recompile and test your code:</p>

<pre><code>$ 6g hello.go &amp;&amp; 6l hello.6 &amp;&amp; ./6.out
Hello, world
</code></pre>

<h3>Square root</h3>

<p>Write a function with this signature</p>

<pre><code>func Sqrt(x float64) float64
</code></pre>

<p>that uses Newton's method to find the square root of <code>n</code>.</p>

<p>In this case, Newton's method is to approximate <code>Sqrt(x)</code> by picking a
starting point <strong>z</strong> and then repeating:</p>

<p><img src="img/sqrt.png" alt="Equation" /></p>

<p>Add some lines to the <code>main</code> function to test your <code>Sqrt</code>.</p>

<pre class="spoiler">package main

import "fmt"

func Sqrt(x float64) float64 {
    var z, d float64 = x, 1
    for d > 1e-15 {
        z0 := z
        z = z - (z*z-x)/(2*z)
        d = z - z0
        if d < 0 {
            d = -d
        }
    }
    return z
}

func main() {
    fmt.Println(9, Sqrt(9))
}

</pre>

<h3>Command-line arguments</h3>

<p>Modify the program to import the <code>flag</code> package and print the command-line
arguments such that running <code>./6.out hello world</code> produces the output:</p>

<pre><code>0 hello
1 world
</code></pre>

<p>Hint: try the command <code>godoc flag Args</code>.</p>

<p>Hint: <code>for i, v := range slice</code> iterates over a slice,
with the key in <code>i</code> and the value in <code>v</code>.</p>

<pre class="spoiler">package main

import (
    "flag"
    "fmt"
)

func main() {
    flag.Parse()
    for i, v := range flag.Args() {
        fmt.Println(i, v)
    }
}

</pre>

<h3>Converting strings to floats</h3>

<p>The <code>strconv</code> package provides functions for converting between strings
and Go's basic types. Use <code>strconv.Atof64</code> function to convert the
command-line arguments. Pass the resulting <code>float64</code> values to your
<code>Sqrt</code> function.</p>

<p>Make sure to check the <code>Atof64</code> function's <code>os.Error</code> return value and
print a diagnostic message if it is not <code>nil</code>.</p>

<pre class="spoiler">package main

import (
    "flag"
    "fmt"
    "strconv"
)

func Sqrt(x float64) float64 {
    var z, d float64 = x, 1
    for d > 1e-15 {
        z0 := z
        z = z - (z*z-x)/(2*z)
        d = z - z0
        if d < 0 {
            d = -d
        }
    }
    return z
}

func main() {
    flag.Parse()
    for _, v := range flag.Args() {
        f, err := strconv.Atof64(v)
        if err != nil {
            fmt.Printf("Couldn't convert %q: %v\n", v, err)
            continue
        }
        fmt.Printf("Sqrt(%v) = %v\n", f, Sqrt(f))
    }
}

</pre>

<h3>Issuing instructions on the command-line</h3>

<p>Set up a switch statement such that <code>./6.out sqrt 9</code> invokes <code>Sqrt(9)</code>
and <code>./6.out exp 2</code> invokes <code>math.Exp(2)</code>, printing the results.</p>

<p>Take a look at the <code>math</code> package and add any other functions you find useful
to the <code>switch</code> statement. (Try adding a function that requires two arguments.)</p>

<pre class="spoiler">package main

import (
    "flag"
    "fmt"
    "math"
    "strconv"
)

func Sqrt(x float64) float64 {
    var z, d float64 = x, 1
    for d > 1e-15 {
        z0 := z
        z = z - (z*z-x)/(2*z)
        d = z - z0
        if d < 0 {
            d = -d
        }
    }
    return z
}

func main() {
    flag.Parse()
    f, err := strconv.Atof64(flag.Arg(1))
    if err != nil {
        fmt.Printf("Couldn't convert %q: %v\n", flag.Arg(1), err)
        return
    }
    switch flag.Arg(0) {
    case "sqrt":
        fmt.Printf("Sqrt(%v) = %v\n", f, Sqrt(f))
    case "cbrt":
        fmt.Printf("Cbrt(%v) = %v\n", f, math.Cbrt(f))
    default:
        fmt.Println("unrecognized command")
    }
}

</pre>

<h2>Session two</h2>

<h3>Hello, web</h3>

<p>Copy this code into a file named <code>web.go</code>:</p>

<pre>package main

import (
    "fmt"
    "http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello, web")
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

</pre>

<p>Build and run it, then visit <a href="http://localhost:8080/">http://localhost:8080/</a>.
You should see the message "Hello, web".</p>

<p>Look at the documentation for the <code>HandleFunc</code> function with <code>godoc http
HandleFunc</code>. Note that it takes a function as its second argument, and
that our <code>handler</code> function matches that function signature.</p>

<h3>Reading request data</h3>

<p>Update the handler function so that it prints "Hello, Fred" when you visit
<a href="http://localhost:8080/?name=Fred">http://localhost:8080/?name=Fred</a>.</p>

<p>Hint: the query data is in <code>r</code>, the <code>*http.Request</code>.</p>

<p>Hint: see <code>godoc http Request</code> and <code>godoc http FormValue</code>.</p>

<p>Hint: call <code>req.FormValue("name")</code>.</p>

<pre class="spoiler">package main

import (
    "fmt"
    "http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Hello, "+r.FormValue("name"))
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

</pre>

<h3>Implementing methods and interfaces</h3>

<p>Implement these types:</p>

<pre><code>type String string

type Struct struct {
    Greeting string
    Punct    string
    Who      string
}
</code></pre>

<p>and define <code>ServeHTTP</code> methods on them. The methods should write the
values themselves to the <code>http.ResponseWriter</code>.</p>

<p>This will allow them to be registered as <code>http.Handler</code>s.  For example:</p>

<pre><code>http.Handle("/string", String("I'm a frayed knot."))
http.Handle("/struct", Struct{"Hello", ":", "Gophers!"})
</code></pre>

<p>Hint: <code>godoc http Handler</code>.</p>

<p>Hint: <code>func (s String) ServeHTTP(w http.ResponseWriter, r *http.Request)</code>.</p>

<p>Hint: use <code>fmt.Fprint</code> to write the value to <code>w</code>.</p>

<pre class="spoiler">package main

import (
    "fmt"
    "http"
)

type String string

func (s String) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, s)
}

type Struct struct {
    Greeting string
    Punct    string
    Who      string
}

func (s Struct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, s)
}

func main() {
    http.Handle("/string", String("I'm a frayed knot."))
    http.Handle("/struct", Struct{"Hello", ":", "Gophers!"})
    http.ListenAndServe(":8080", nil)
}

</pre>

<h3>Drawing an image</h3>

<p>Copy this code into a new file, <code>image.go</code>:</p>

<pre>package main

import (
    "http"
    "image"
    "image/png"
)

var m image.Image

func img(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-type", "image/png")
    png.Encode(w, m)
}

func main() {
    rgba := image.NewRGBA(300, 300)
    for x := 0; x < 300; x++ {
        for y := 0; y < 300; y++ {
            rgba.Set(x, y, image.RGBAColor{0, 0, 0, 255})
        }
    }
    m = rgba
    http.HandleFunc("/", img)
    http.ListenAndServe(":8080", nil)
}

</pre>

<p>This code implements a web server that serves a 300 by 300 pixel black PNG
image. Try changing the color of the image.</p>

<p>The <code>image.NewRGBA</code> function returns an <code>*image.RGBA</code> that imlements the
<code>image.Image</code> interface; that's why we can assign <code>rgba</code> to the global
variable <code>m</code>.</p>

<pre><code>type Image interface {
    // ColorModel returns the Image's ColorModel.
    ColorModel() ColorModel
    // Bounds returns the domain for which At can return non-zero color.
    Bounds() Rectangle
    // At returns the color of the pixel at (x, y).
    At(x, y int) Color
}
</code></pre>

<h3>Implement the <code>image.Image</code> interface</h3>

<p>Let's implement our own <code>image.Image</code>. Drop the first 7 lines of the <code>main</code>
function, and create a new type:</p>

<pre><code>type MyImage struct {
    width, height int
}
</code></pre>

<p>Then implement the methods of the <code>image.Image</code> interface on <code>MyImage</code>.
That's <code>ColorModel</code>, <code>Bounds</code>, and <code>At</code>; refer to the <code>Image</code> interface type
definition above for their signatures and meanings.</p>

<p><code>ColorModel</code> should just return <code>image.RGBAColorModel</code>, to instruct anything
that uses <code>MyImage</code> that it is an image composed of <code>RGBA</code>.</p>

<p><code>Bounds</code> should return an <code>image.Rectangle</code> with the top-left point <code>0, 0</code>
and the top right point <code>width, height</code> (where <code>width</code> and <code>height</code> are the
values from the <code>MyImage</code> struct).</p>

<p><code>At</code> should return an <code>image.RGBAColor</code> value driven by some function of the
<code>x</code> and <code>y</code> coordinate; intesting functions include <code>x^y</code>, <code>(x+y)/2</code>, and
<code>x*y</code>. (Make sure you set the alpha field (the last one) to 255 or the pixel
will be transparent.)</p>

<p>Once you've done this, assign a <code>MyImage</code> value of <code>m</code> at the top of
your <code>main</code> function. (<code>m = MyImage{300, 300}</code>)</p>

<p>Hint: the <code>Image</code> interface is defined in the <code>image</code> package, so all the
unqualified types in the function signatures should be qualified with a 
package name (<code>Rectangle</code> should be <code>image.Rectangle</code>, for example).</p>

<pre class="spoiler">package main

import (
    "http"
    "image"
    "image/png"
)

var m image.Image

func img(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-type", "image/png")
    png.Encode(w, m)
}

type MyImage struct {
    width, height int
}

func (m MyImage) ColorModel() image.ColorModel {
    return image.RGBAColorModel
}

func (m MyImage) Bounds() image.Rectangle {
    return image.Rect(0, 0, m.width, m.height)
}

func (m MyImage) At(x, y int) image.Color {
    c := uint8(x*x + y*y)
    return image.RGBAColor{c, c, c, 255}
}

func main() {
    m = MyImage{300, 300}
    http.HandleFunc("/", img)
    http.ListenAndServe(":8080", nil)
}

</pre>

<h2>Conclusions</h2>

<p>We've really only scratched the surface with this tutorial, but I hope that you
now have the knoweldge and confidence to delve deeper into Go on your own.</p>

<p>There is a wealth of Go resources&mdash;including more tutorials and code
labs&mdash;available at <a href="http://golang.org/">golang.org</a>.</p>

